import $ from 'jquery'
import katex from 'katex'

function make(tag, content, attrs) {
    let attrs_ = ''

    for (const key in attrs) {
        attrs_ += `${key}="${attrs[key]}" `
    }
    return `<${tag} ${attrs_}>${content}</${tag}>`
}

let Global = 1
const fontSize = 24

let svgWidth = 0
let svgHeight = 0

function max(a, b) {
    return a > b ? a : b
}

class Node {
    constructor(title, level, parent, idx) {
        this.title = title
        this.level = level
        this.parent = parent
        this.children = []
        this.idx = idx
    }

    draw() {
        // let n = Math.ceil(this.parent.children.length / 2)

        let tag
        let content = this.title
        let style = 'fill:white'

        svgWidth = max(svgWidth, this.x + this.width)
        svgHeight = max(svgHeight, this.y + this.height)
        if (content.startsWith('url:')) {
            let href = content.split(' ')[2]
            content = content.split(' ')[1]
            style = 'fill:#54ff00'
            let textTag = make('text', content, {
                x: this.x,
                y: this.y,
                width: this.width,
                height: this.height,
                style: style
            })
            tag = make('a', textTag, {
                'xlink:href': href,
                target: '_blank',
            })
        } else if (content.startsWith('latex:')) {
            let latex = content.split(' ')[1]

            tag = make('text', latex, {
                x: this.x,
                y: this.y,
                width: this.width,
                height: this.height,
                style: style
            })
        } else if (content.startsWith('-> ')) {
            let href = '/#/home/' + content.split(' ')[2]
            content = content.split(' ')[1]
            style = 'fill:yellow'

            let textTag = make('text', content, {
                x: this.x,
                y: this.y,
                width: this.width,
                height: this.height,
                style: style
            })
            tag = make('a', textTag, {
                'xlink:href': href,
                target: '_self',
            })
        } else {
            tag = make('text', content, {
                x: this.x,
                y: this.y,
                width: this.width,
                height: this.height,
                style: style
            })
        }

        const ax = this.parent.x + this.parent.width + 10
        const ay = this.parent.y
        const bx = this.x
        const by = this.y
        let cy = (this.idx - 0) - (this.parent.children.length - 1 - this.idx)
        if (cy < 0) {
            cy = by + 10
        } else if (cy > 0) {
            cy = by - 10
        } else {
            cy = by
        }

        this.ax = ax
        this.ay = ay
        this.bx = bx
        this.by = by
        this.cy = cy

        let pathTag = ''
        if (this.title !== 'ROOT') {
            pathTag = make('path', '', {
                // d: `M ${ax} ${ay} L ${ax} ${by} L ${bx} ${by}`,
                d: `M ${ax} ${ay} L ${ax} ${cy} Q ${ax} ${by} ${ax + 10} ${by} L ${bx} ${by}`,
                stroke: 'white',
                fill: 'none'
            })
        }

        let ret = ''
        let data = {
            x: this.x,
            y: this.y,
            width: this.width,
            height: this.height,
            title: this.title,

            ax,
            ay,
            bx,
            by,
            cy,

            children: [],
        }
        let m = Math.ceil(this.children.length / 2)

        for (let i = 0; i < m; i++) {
            let X = this.children[i].draw()
            ret += X[0]
            data.children.push(X[1])
        }
        ret += tag + pathTag

        for (let i = m; i < this.children.length; i++) {
            let X = this.children[i].draw()
            ret += X[0]
            data.children.push(X[1])
        }

        return [ret, data]
    }

    reSize() {
        for (let child of this.children) {
            child.reSize()
        }
        if (this.children.length === 0) {
            this.y = 2 * fontSize * Global++
        } else {
            this.y = (this.children[0].y + this.children[this.children.length - 1].y) / 2
        }
    }
}

function init(nodes) {
    Global = 1
    const ROOTParent = {}
    ROOTParent.x = 0
    ROOTParent.y = 0
    ROOTParent.width = 0
    ROOTParent.height = 0
    ROOTParent.indent = 0

    ROOTParent.children = [root]

    let lastLevel = -1
    let root = new Node('ROOT', -1, ROOTParent, 0)
    root.x = -96
    root.y = 0
    root.width = 0
    root.height = 0
    root.indent = 0

    let parents = [root]
    let parent = null

    for (let idx = 0; idx < nodes.length; idx++) {
        const node_ = nodes[idx]

        const title = node_.title
        const level = node_.level

        if (level > lastLevel) {
            parent = parents[parents.length - 1]
        } else {
            for (let i = 0; i < lastLevel - level + 1; i++) {
                parents.pop()
            }
            parent = parents[parents.length - 1]
        }

        const node = new Node(title, level, parent, parent.children.length)
        parent.children.push(node)
        parents.push(node)
        lastLevel = level

        if (node.title.startsWith('latex:')) {
            let html = katex.renderToString(node.title.slice(7), {
                throwOnError: false
            })
            $('#calculateWidth').append($(make('span', html, {'class': 'hidden', 'style': 'display:inline-block'})))

        } else {
            let title = node.title.startsWith('->') || node.title.startsWith('url: ') ? node.title.split(' ')[1] : node.title
            $('#calculateWidth').append($(make('span', title, {
                'class': 'hidden',
                'style': 'display:inline-block'
            })))

        }
        let width = $(`.hidden:last-child`).width()
        if (node.title.startsWith('latex:')) {
            width += 20
        } else {
            width += 20
        }
        $(`.hidden:last-child`).remove()
        const height = fontSize * 2 + 20

        const tabs = 4
        const x = parent.x + parent.width + fontSize * tabs
        const y = fontSize * (2 * idx + 1)

        node.x = x
        node.y = y
        node.width = width
        node.height = height
    }
    return draw(root)
}

function draw(ROOTParent) {
    ROOTParent.reSize()
    let X = ROOTParent.draw()
    // const svg = `<svg xmlns="http://www.w3.org/2000/svg" version="1.1"></svg>`
    // const svg = `<svg xmlns="http://www.w3.org/2000/svg" version="1.1">${X[0]}</svg>`


    $('.svg').width(svgWidth).height(svgHeight)
    console.log(svgWidth, svgHeight)
    let svgHeightOld = max(svgHeight + 5, 500)
    let svgWidthOld = svgWidth + 5
    svgWidth = 0
    svgHeight = 0
    return {
        data: X[1].children[0],
        width: svgWidthOld,
        height: svgHeightOld,
    }
}

export default init;
